<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
<style>
body {
  font-family: Helvetica, arial, sans-serif;
  font-size: 14px;
  line-height: 1.6;
  padding-top: 10px;
  padding-bottom: 10px;
  background-color: white;
  padding: 30px; }

body > *:first-child {
  margin-top: 0 !important; }
body > *:last-child {
  margin-bottom: 0 !important; }

a {
  color: #4183C4; }
a.absent {
  color: #cc0000; }
a.anchor {
  display: block;
  padding-left: 30px;
  margin-left: -30px;
  cursor: pointer;
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0; }

h1, h2, h3, h4, h5, h6 {
  margin: 20px 0 10px;
  padding: 0;
  font-weight: bold;
  -webkit-font-smoothing: antialiased;
  cursor: text;
  position: relative; }

h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, h5:hover a.anchor, h6:hover a.anchor {
  background: url() no-repeat 10px center;
  text-decoration: none; }

h1 tt, h1 code {
  font-size: inherit; }

h2 tt, h2 code {
  font-size: inherit; }

h3 tt, h3 code {
  font-size: inherit; }

h4 tt, h4 code {
  font-size: inherit; }

h5 tt, h5 code {
  font-size: inherit; }

h6 tt, h6 code {
  font-size: inherit; }

h1 {
  font-size: 28px;
  color: black; }

h2 {
  font-size: 24px;
  border-bottom: 1px solid #cccccc;
  color: black; }

h3 {
  font-size: 18px; }

h4 {
  font-size: 16px; }

h5 {
  font-size: 14px; }

h6 {
  color: #777777;
  font-size: 14px; }

p, blockquote, ul, ol, dl, li, table, pre {
  margin: 15px 0; }

hr {
  background: transparent url() repeat-x 0 0;
  border: 0 none;
  color: #cccccc;
  height: 4px;
  padding: 0;
}

body > h2:first-child {
  margin-top: 0;
  padding-top: 0; }
body > h1:first-child {
  margin-top: 0;
  padding-top: 0; }
  body > h1:first-child + h2 {
    margin-top: 0;
    padding-top: 0; }
body > h3:first-child, body > h4:first-child, body > h5:first-child, body > h6:first-child {
  margin-top: 0;
  padding-top: 0; }

a:first-child h1, a:first-child h2, a:first-child h3, a:first-child h4, a:first-child h5, a:first-child h6 {
  margin-top: 0;
  padding-top: 0; }

h1 p, h2 p, h3 p, h4 p, h5 p, h6 p {
  margin-top: 0; }

li p.first {
  display: inline-block; }
li {
  margin: 0; }
ul, ol {
  padding-left: 30px; }

ul :first-child, ol :first-child {
  margin-top: 0; }

dl {
  padding: 0; }
  dl dt {
    font-size: 14px;
    font-weight: bold;
    font-style: italic;
    padding: 0;
    margin: 15px 0 5px; }
    dl dt:first-child {
      padding: 0; }
    dl dt > :first-child {
      margin-top: 0; }
    dl dt > :last-child {
      margin-bottom: 0; }
  dl dd {
    margin: 0 0 15px;
    padding: 0 15px; }
    dl dd > :first-child {
      margin-top: 0; }
    dl dd > :last-child {
      margin-bottom: 0; }

blockquote {
  border-left: 4px solid #dddddd;
  padding: 0 15px;
  color: #777777; }
  blockquote > :first-child {
    margin-top: 0; }
  blockquote > :last-child {
    margin-bottom: 0; }

table {
  padding: 0;border-collapse: collapse; }
  table tr {
    border-top: 1px solid #cccccc;
    background-color: white;
    margin: 0;
    padding: 0; }
    table tr:nth-child(2n) {
      background-color: #f8f8f8; }
    table tr th {
      font-weight: bold;
      border: 1px solid #cccccc;
      margin: 0;
      padding: 6px 13px; }
    table tr td {
      border: 1px solid #cccccc;
      margin: 0;
      padding: 6px 13px; }
    table tr th :first-child, table tr td :first-child {
      margin-top: 0; }
    table tr th :last-child, table tr td :last-child {
      margin-bottom: 0; }

img {
  max-width: 100%; }

span.frame {
  display: block;
  overflow: hidden; }
  span.frame > span {
    border: 1px solid #dddddd;
    display: block;
    float: left;
    overflow: hidden;
    margin: 13px 0 0;
    padding: 7px;
    width: auto; }
  span.frame span img {
    display: block;
    float: left; }
  span.frame span span {
    clear: both;
    color: #333333;
    display: block;
    padding: 5px 0 0; }
span.align-center {
  display: block;
  overflow: hidden;
  clear: both; }
  span.align-center > span {
    display: block;
    overflow: hidden;
    margin: 13px auto 0;
    text-align: center; }
  span.align-center span img {
    margin: 0 auto;
    text-align: center; }
span.align-right {
  display: block;
  overflow: hidden;
  clear: both; }
  span.align-right > span {
    display: block;
    overflow: hidden;
    margin: 13px 0 0;
    text-align: right; }
  span.align-right span img {
    margin: 0;
    text-align: right; }
span.float-left {
  display: block;
  margin-right: 13px;
  overflow: hidden;
  float: left; }
  span.float-left span {
    margin: 13px 0 0; }
span.float-right {
  display: block;
  margin-left: 13px;
  overflow: hidden;
  float: right; }
  span.float-right > span {
    display: block;
    overflow: hidden;
    margin: 13px auto 0;
    text-align: right; }

code, tt {
  margin: 0 2px;
  padding: 0 5px;
  white-space: nowrap;
  border: 1px solid #eaeaea;
  background-color: #f8f8f8;
  border-radius: 3px; }

pre code {
  margin: 0;
  padding: 0;
  white-space: pre;
  border: none;
  background: transparent; }

.highlight pre {
  background-color: #f8f8f8;
  border: 1px solid #cccccc;
  font-size: 13px;
  line-height: 19px;
  overflow: auto;
  padding: 6px 10px;
  border-radius: 3px; }

pre {
  background-color: #f8f8f8;
  border: 1px solid #cccccc;
  font-size: 13px;
  line-height: 19px;
  overflow: auto;
  padding: 6px 10px;
  border-radius: 3px; }
  pre code, pre tt {
    background-color: transparent;
    border: none; }

sup {
    font-size: 0.83em;
    vertical-align: super;
    line-height: 0;
}
* {
	-webkit-print-color-adjust: exact;
}
@media screen and (min-width: 914px) {
    body {
        width: 854px;
        margin:0 auto;
    }
}
@media print {
	table, pre {
		page-break-inside: avoid;
	}
	pre {
		word-wrap: break-word;
	}
}
</style>
<title>外观</title>

</head>
<body>
<h1>外观</h1>

<ul>
<li><a href="#introduction">简介</a></li>
<li><a href="#explanation">解释</a></li>
<li><a href="#practical-usage">实际应用</a></li>
<li><a href="#creating-facades">创建外观</a></li>
<li><a href="#mocking-facades">模拟外观</a></li>
</ul>


<p><a name="introduction"></a></p>

<h2>简介</h2>

<p>Facades 为应用程序的 <a href="/docs/ioc">IoC容器</a> 的类提供了一个静态的接口。Laravel 自带很多外观，也许您已经使用它们但并没有意识到。</p>

<p>有时候，您可能希望为您的应用程序和包创建您自己的外观，让我们探讨它们的概念、开发以及使用。</p>

<blockquote><p><strong>注意:</strong> 强烈建议您非常熟悉 Laravel 的 <a href="/docs/ioc">IoC容器</a> 之后再深入探讨外观。</p></blockquote>

<p><a name="explanation"></a></p>

<h2>解释</h2>

<p>在 Laravel 应用程序的上下文环境中，外观是一个为来自容器的一个对象提供访问的类。实际工作是 <code>Facade</code> 类。Laravel 的外观和您创建的外观都继承自 <code>Facade</code> 类。</p>

<p>您的外观类只需要实现一个函数：<code>getFacadeAccessor</code>。正是这个 <code>getFacadeAccessor</code> 函数的功能定义了从容器中怎样解析。<code>Facade</code> 基础类使用 <code>__callStatic()</code> 魔方函数来推迟来自您的外观到解析对象的调用。</p>

<p><a name="practical-usage"></a></p>

<h2>实际应用</h2>

<p>在下面的例子中，调用了 Laravel 的缓存系统。通过浏览这段代码，人们可能认为静态类 <code>get</code> 被 <code>Cache</code> 类调用。</p>

<pre><code>$value = Cache::get('key');
</code></pre>

<p>但是，如果我们看看 <code>Illuminate\Support\Facades\Cache</code> 类，您会发现并没有静态方法 <code>get</code>：</p>

<pre><code>class Cache extends Facade {

    /**
     * Get the registered name of the component.
     *
     * @return string
     */
    protected static function getFacadeAccessor() { return 'cache'; }

}
</code></pre>

<p>Cache 类继承自基类 <code>Facade</code> 并且定义了一个 <code>getFacadeAccessor()</code> 函数。记住，这个函数的工作就是返回 IoC 绑定的名字。</p>

<p>当一个用户在 <code>Cache</code> 外观中引用任何静态函数，Laravel 将从 IoC 容器解析 <code>cache</code> 绑定并针对该对象运行请求的函数（在这个例子中是 <code>get</code>）。</p>

<p>所以，我们的 <code>Cache::get</code> 调用将被像这样重写:</p>

<pre><code>$value = $app-&gt;make('cache')-&gt;get('key');
</code></pre>

<p><a name="creating-facades"></a></p>

<h2>创建外观</h2>

<p>为您的应用程序或包创建一个外观是简单的，您只需要三件事：</p>

<ul>
<li>一个 IoC 绑定</li>
<li>一个外观类</li>
<li>一个外观别名的配置</li>
</ul>


<p>让我们看一个例子，在这里，我们定义了一个 <code>PaymentGateway\Payment</code> 类：</p>

<pre><code>namespace PaymentGateway;

class Payment {

    public function process()
    {
        //
    }

}
</code></pre>

<p>我们需要能够从 IoC 容器中解析这个类。所以，让我们添加一个绑定：</p>

<pre><code>App::bind('payment', function()
{
    return new \PaymentGateway\Payment;
});
</code></pre>

<p>一个很好的地方注册这个绑定是创建一个新的名为 <code>PaymentServiceProvider</code> 的 <a href="/docs/ioc#service-providers">服务提供者</a>，并且使用 <code>register</code> 添加这个绑定。然后您可以配置 Laravel 从 <code>app/config/app.php</code> 文件中加载您的服务提供商。</p>

<p>接下来，我们可以创建自己的外观类：</p>

<pre><code>use Illuminate\Support\Facades\Facade;

class Payment extends Facade {

    protected static function getFacadeAccessor() { return 'payment'; }

}
</code></pre>

<p>最后，如果我们愿意，我们可以为我们的外观在 <code>app/config/app.php</code> 配置文件中添加一个别名到 <code>aliases</code>  数组。现在，我们可以对 <code>Payment</code> 类的实例调用 <code>process</code> 函数。</p>

<pre><code>Payment::process();
</code></pre>

<p><a name="mocking-facades"></a></p>

<h2>模拟外观</h2>

<p>单元测试是一个重要的方面关于为什么外观能够以它们的方式工作。事实上，可测试性是外观存在的一个主要的原因。跟多信息，请参阅 <a href="/docs/testing#mocking-facades">模拟外观</a> 部分的文档。</p>
</body>
</html>